<!-- @format -->

<template>
  <view
    class="comp-input"
    :class="[
      `comp-input--${type}`,
      { 'comp-input--disabled': disabled },
      { 'comp-input--readonly': readonly },
      { 'comp-input--error': error },
      { 'comp-input--focus': isFocused },
      { 'comp-input--with-label': label },
      { 'comp-input--with-prefix': $slots.prefix },
      { 'comp-input--with-suffix': $slots.suffix || clearable || showPasswordToggle },
    ]"
  >
    <!-- 标签 -->
    <view v-if="label" class="comp-input__label">
      <slot name="label">{{ label }}</slot>
    </view>

    <view class="comp-input__wrapper">
      <!-- 前缀图标 -->
      <view v-if="$slots.prefix" class="comp-input__prefix">
        <slot name="prefix"></slot>
      </view>

      <!-- 输入框 -->
      <view class="comp-input__field-wrapper">
        <input
          v-if="type !== 'textarea'"
          ref="inputRef"
          :value="modelValue"
          :type="showPassword ? 'text' : type"
          :placeholder="placeholder"
          :disabled="disabled"
          :readonly="readonly"
          :maxlength="maxlength"
          :autocomplete="autocomplete"
          :name="name"
          :id="id"
          class="comp-input__field"
          @input="handleInput"
          @focus="handleFocus"
          @blur="handleBlur"
          @keydown="handleKeyDown"
          confirm-type="done"
        />
        <textarea
          v-else
          ref="inputRef"
          class="comp-input__textarea"
          :value="modelValue"
          :placeholder="placeholder"
          :disabled="disabled"
          :readonly="readonly"
          :maxlength="maxlength"
          :auto-height="false"
          :show-confirm-bar="false"
          :autocomplete="autocomplete"
          :name="name"
          :id="id"
          @input="handleInput"
          @focus="handleFocus"
          @blur="handleBlur"
          @keydown="handleKeyDown"
        ></textarea>
      </view>

      <!-- 后缀图标区域 -->
      <view
        v-if="$slots.suffix || clearable || showPasswordToggle"
        class="comp-input__suffix"
      >
        <!-- 清除按钮 -->
        <view
          v-if="clearable && modelValue && !disabled && !readonly"
          class="comp-input__clear"
          @click="handleClear"
        >
          <text class="comp-input__clear-icon">×</text>
        </view>

        <!-- 密码显示切换 -->
        <view
          v-if="type === 'password' && showPasswordToggle && !disabled && !readonly"
          class="comp-input__password-toggle"
          @click="togglePasswordVisibility"
        >
          <text class="comp-input__password-icon">
            {{ showPassword ? '👁️' : '👁️‍🗨️' }}
          </text>
        </view>

        <!-- 自定义后缀 -->
        <slot name="suffix"></slot>
      </view>
    </view>

    <!-- 字数统计 -->
    <view v-if="showWordLimit && maxlength" class="comp-input__word-limit">
      <text class="comp-input__word-count">{{ modelValue?.length || 0 }}</text>
      <text class="comp-input__word-separator">/</text>
      <text class="comp-input__word-max">{{ maxlength }}</text>
    </view>

    <!-- 错误提示 -->
    <view v-if="error && errorMessage" class="comp-input__error-message">
      {{ errorMessage }}
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch, useSlots, getCurrentInstance } from 'vue'

// 定义输入框属性
interface Props {
  /** 绑定值 */
  modelValue: string
  /** 输入框类型 */
  type?: 'text' | 'password' | 'number' | 'tel' | 'textarea' | 'email' | 'url' | 'search'
  /** 输入框占位文本 */
  placeholder?: string
  /** 是否禁用 */
  disabled?: boolean
  /** 是否只读 */
  readonly?: boolean
  /** 最大输入长度 */
  maxlength?: number
  /** 是否显示字数统计 */
  showWordLimit?: boolean
  /** 是否可清空 */
  clearable?: boolean
  /** 标签文本 */
  label?: string
  /** 是否显示密码切换按钮 */
  showPasswordToggle?: boolean
  /** 是否有错误 */
  error?: boolean
  /** 错误提示消息 */
  errorMessage?: string
  /** 自动完成属性 */
  autocomplete?: string
  /** 文本域行数 */
  rows?: number
  /** 输入框名称 */
  name?: string
  /** 输入框ID */
  id?: string
}

// 定义默认属性
const props = withDefaults(defineProps<Props>(), {
  type: 'text',
  placeholder: '',
  disabled: false,
  readonly: false,
  maxlength: 1000,
  showWordLimit: false,
  clearable: false,
  label: '',
  showPasswordToggle: false,
  error: false,
  errorMessage: '',
  autocomplete: 'off',
  rows: 3,
  name: '',
  id: ''
})

// 定义事件
const emit = defineEmits<{
  /** 更新绑定值 */
  (e: 'update:modelValue', value: string): void
  /** 输入事件 */
  (e: 'input', event: Event): void
  /** 获得焦点事件 */
  (e: 'focus', event: FocusEvent): void
  /** 失去焦点事件 */
  (e: 'blur', event: FocusEvent): void
  /** 按键事件 */
  (e: 'keydown', event: KeyboardEvent): void
  /** 清空事件 */
  (e: 'clear'): void
}>()

// 获取插槽
const $slots = useSlots()

// 输入框引用
const inputRef = ref<HTMLInputElement | HTMLTextAreaElement | null>(null)

// 是否聚焦
const isFocused = ref(false)

// 是否显示密码
const showPassword = ref(false)

// 处理输入事件
const handleInput = (event: any) => {
  const value = event.detail?.value || '';
  emit('update:modelValue', value);
  emit('input', event);
};


// 处理聚焦事件
const handleFocus = (event: any) => {
  isFocused.value = true;
  emit('focus', event);
};

// 处理失焦事件
const handleBlur = (event: any) => {
  isFocused.value = false;
  emit('blur', event);
};

// 处理按键事件
const handleKeyDown = (event: any) => {
  emit('keydown', event);
};

// 处理清空事件
const handleClear = () => {
  emit('update:modelValue', '')
  emit('clear')
  // 聚焦回输入框
  inputRef.value?.focus()
}

// 切换密码可见性
const togglePasswordVisibility = () => {
  showPassword.value = !showPassword.value
}

// 暴露方法
defineExpose({
  /** 聚焦输入框 */
  focus: () => {
    if (inputRef.value) {
      // 在uni-app中，需要使用uni.createSelectorQuery来获取元素并操作
      const query = uni.createSelectorQuery().in(getCurrentInstance());
      query.select('#' + (props.id || 'comp-input')).node(res => {
        if (res && res.node) {
          res.node.focus();
        }
      }).exec();
    }
  },
  /** 失焦输入框 */
  blur: () => {
    if (inputRef.value) {
      // 在uni-app中，需要使用uni.createSelectorQuery来获取元素并操作
      const query = uni.createSelectorQuery().in(getCurrentInstance());
      query.select('#' + (props.id || 'comp-input')).node(res => {
        if (res && res.node) {
          res.node.blur();
        }
      }).exec();
    }
  },
  /** 选择输入框内容 */
  select: () => {
    // uni-app环境中没有直接的select方法，可以通过focus后模拟选择
    if (inputRef.value) {
      const query = uni.createSelectorQuery().in(getCurrentInstance());
      query.select('#' + (props.id || 'comp-input')).node(res => {
        if (res && res.node) {
          res.node.focus();
        }
      }).exec();
    }
  }
})
</script>

<style lang="scss">
.comp-input {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  font-size: 14px;
  margin-bottom: 16px;

  &__label {
    margin-bottom: 8px;
    font-weight: 500;
    color: #323233;
  }

  &__wrapper {
    position: relative;
    display: flex;
    align-items: center;
    width: 100%;
    min-height: 40px;
    padding: 0;
    background-color: #fff;
    border: 1px solid #dcdee0;
    border-radius: 4px;
    transition: all 0.3s;
  }

  &__field-wrapper {
    flex: 1;
    position: relative;
  }

  &__field,
  &__textarea {
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-height: 40px;
    margin: 0;
    padding: 8px 12px;
    color: #323233;
    font-size: 14px;
    line-height: 24px;
    background-color: transparent;
    border: none;
    outline: none;
    resize: none;

    &::placeholder {
      color: #c8c9cc;
    }
  }

  &__textarea {
    padding: 8px 12px;
  }

  &__prefix,
  &__suffix {
    display: flex;
    align-items: center;
    padding: 0 12px;
    color: #969799;
  }

  &__clear,
  &__password-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    color: #c8c9cc;
    cursor: pointer;
    transition: color 0.3s;

    &:hover {
      color: #969799;
    }
  }

  &__word-limit {
    margin-top: 4px;
    text-align: right;
    color: #969799;
    font-size: 12px;
  }

  &__error-message {
    margin-top: 4px;
    color: #ee0a24;
    font-size: 12px;
  }

  // 状态样式
  &--focus {
    .comp-input__wrapper {
      border-color: #1989fa;
    }
  }

  &--disabled {
    opacity: 0.6;
    cursor: not-allowed;

    .comp-input__field,
    .comp-input__textarea {
      cursor: not-allowed;
    }
  }

  &--readonly {
    .comp-input__field,
    .comp-input__textarea {
      cursor: default;
    }
  }

  &--error {
    .comp-input__wrapper {
      border-color: #ee0a24;
    }

    .comp-input__field,
    .comp-input__textarea {
      color: #ee0a24;
    }
  }
}
</style>